package com.abu.cms.controller;

import com.abu.cms.client.EduClient;
import com.abu.pojo.Course;
import com.abu.pojo.Teacher;
import com.abu.utils.Resp;
import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Random;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("educms")
public class IndexFrontController {

    @Autowired
    private EduClient eduClient;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private RedissonClient redissonClient;

    private static final String PREFIX_TEACHERS = "INDEX.FRONT.TEACHER";
    private static final String PREFIX_COURSE = "INDEX.FRONT.COURSE";

    /**
     * 首页并发量高，通过加缓存来缓解 查询名师和新课程
     *
     * @return
     */
    @GetMapping("indexfront/index")
    public Resp queryLimit() {
//        1. 先查询缓存有没有
        String courses = this.redisTemplate.opsForValue().get(PREFIX_COURSE);
        String teachers = this.redisTemplate.opsForValue().get(PREFIX_TEACHERS);
//        2.有的话直接返回
        if (StringUtils.isNotBlank(courses) && StringUtils.isNotBlank(teachers)) {
            List<Course> courseList = JSON.parseArray(courses, Course.class);
            List<Teacher> teacherList = JSON.parseArray(teachers, Teacher.class);
            return Resp.ok().data("teacherList", teacherList).data("eduList", courseList);
        }
//        3.没有的话加分布式锁(解决缓存击穿)
        RLock lock = this.redissonClient.getLock("lock");
        lock.lock();
//        4.再次查询缓存
        String courses02 = this.redisTemplate.opsForValue().get(PREFIX_COURSE);
        String teachers02 = this.redisTemplate.opsForValue().get(PREFIX_TEACHERS);
        if (StringUtils.isNotBlank(courses02) && StringUtils.isNotBlank(teachers02)) {
            List<Course> courseList = JSON.parseArray(courses02, Course.class);
            List<Teacher> teacherList = JSON.parseArray(teachers02, Teacher.class);
//        5.有的话直接返回
            lock.unlock();
            return Resp.ok().data("teacherList", teacherList).data("eduList", courseList);
        }
//        6.没有的话查询数据库
//        根据水平由高到底进行查询
        List<Teacher> teacherList = this.eduClient.queryIndexTeachers();
//        根据课程添加时间进行查询
        List<Course> courseList = this.eduClient.queryIndexCourses();

//        7.将结果集放入缓存中（将查询出的不存在的数据也放入缓存中，解决了缓存穿透。将缓存过期时间设置成了随机值，防止缓存雪崩）
        this.redisTemplate.opsForValue().set(PREFIX_TEACHERS, JSON.toJSONString(teacherList), 60 * new Random().nextInt(100) + 1, TimeUnit.SECONDS);
        this.redisTemplate.opsForValue().set(PREFIX_COURSE, JSON.toJSONString(courseList), 60 * new Random().nextInt(50) + 1, TimeUnit.SECONDS);
//        释放锁
        lock.unlock();
        return Resp.ok().data("teacherList", teacherList).data("eduList", courseList);
    }
}
